package cn.edu.zime.tjh.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;

public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    private static ConcurrentHashMap<String, ChannelHandlerContext> allClients = new ConcurrentHashMap<>();
    private static BiConsumer<String, String> logCallback;

    public EchoServerHandler(){

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        String clientId = ctx.channel().remoteAddress().toString();
        allClients.put(clientId, ctx);
        String message = "客户端已连接: " + clientId;
        System.out.println(message);
        if (logCallback != null) {
            logCallback.accept(message, "连接");
        }
        
        String totalMessage = "总客户端数: " + allClients.size();
        System.out.println(totalMessage);
        if (logCallback != null) {
            logCallback.accept(totalMessage, "状态");
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        // 收到消息直接原样写回
        String received = (String) msg;
        String clientId = getClientId(ctx);
        String logMessage = "收到来自 " + clientId + " 的消息: " + received;
        System.out.println(logMessage);
        if (logCallback != null) {
            logCallback.accept(logMessage, "接收");
        }
        
        ctx.writeAndFlush(received);  // 注意：这里会自动释放msg
        
        String echoMessage = "回显给 " + clientId + ": " + received;
        System.out.println(echoMessage);
        if (logCallback != null) {
            logCallback.accept(echoMessage, "发送");
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        String clientId = getClientId(ctx);
        if (clientId != null) {
            allClients.remove(clientId);
            String message = "客户端已断开: " + clientId;
            System.out.println(message);
            if (logCallback != null) {
                logCallback.accept(message, "断开");
            }
        }
    }


    private String getClientId(ChannelHandlerContext ctx) {
        for (Map.Entry<String, ChannelHandlerContext> entry : allClients.entrySet()) {
            if (entry.getValue().equals(ctx)) {
                return entry.getKey();
            }
        }
        return null;
    }

    // 广播消息给所有客户端
    public static void broadcastMessage(String message) {
        for (ChannelHandlerContext ctx : allClients.values()) {
            if (ctx.channel().isActive()) {
                ctx.writeAndFlush("[服务器广播]: " + message);
            }
        }
        String logMessage = "已广播给 " + allClients.size() + " 个客户端: " + message;
        System.out.println(logMessage);
        if (logCallback != null) {
            logCallback.accept(logMessage, "广播");
        }
    }

    // 发送消息给特定客户端
    public static void sendMessageToClient(String clientId, String message) {
        ChannelHandlerContext ctx = allClients.get(clientId);
        if (ctx != null && ctx.channel().isActive()) {
            ctx.writeAndFlush("[服务器消息]: " + message);
            String logMessage = "已发送给客户端 " + clientId + ": " + message;
            System.out.println(logMessage);
            if (logCallback != null) {
                logCallback.accept(logMessage, "发送");
            }
        } else {
            String errorMessage = "客户端 " + clientId + " 未找到或已断开";
            System.out.println(errorMessage);
            if (logCallback != null) {
                logCallback.accept(errorMessage, "错误");
            }
        }
    }

    // 获取所有连接的客户端ID
    public static String[] getAllClientIds() {
        return allClients.keySet().toArray(new String[0]);
    }

    // 获取客户端数量
    public static int getClientCount() {
        return allClients.size();
    }
    
    // 设置日志回调
    public static void setLogCallback(BiConsumer<String, String> callback) {
        logCallback = callback;
    }
}
